[Back]

Rhapsody Developer Release © Copyright 1998 by Apple Computer, Inc. All Rights Reserved.

Rhapsody Developer Release Notes:
Debugging

 

This file contains release notes for the Developer Release 2 of the gdb and jdb command-line debuggers, and of the Project Builder visual debugging facilities. The section in this document are:

gdb
A command-line debugger for C, Objective-C, and C++ programs
jdb
A command-line debugger for Java applets and 100% Pure JavaTM programs
Project Builder
Visual debugging for C, Objective-C, and C++ programs using gdb and Java debugging using the Java debugger.
Java Debugger Command Reference
A summary of the commands for the Java debugger

 

Notes Specific to gdb

The gdb program is the GNU source-level Debugger. For more information, see the debugging documentation in /System/Documentation/Developer/Yellow Box/Reference/DevTools/Debugger. On Rhapsody, you can also refer to the gdb (1) manual page

 

New Features

The gdb debugger in this release (/usr/bin/gdb) is based on version 4.14 released by the Free Software Foundation (FSF). A newer version of gdb (/usr/bin/gdb-4.17), based on the gdb-971126 snapshot from Cygnus, is also available. Although still incomplete, this newer version of gdb offers better support areas such as signal handling, attaching to running processes, and dynamic library loading, as well as a number of bug fixes. If a feature in gdb doesn't work properly, you might try using gdb-4.17. For the most up-to-date information on gdb, see the Rhapsody Developer Release website in Apple Developer World

 

Major Changes from gdb to gdb-4.17

The version of gdb for Yellow Box for Windows has not changed from the Developer Release.

 

Known Problems for gdb

The Sybase Client Library and Multithreaded Programs

gdb hangs (actually, the new Sybase CT-Lib adaptor blocks) when you use the next command to step over a line of code which eventually causes a call to the Sybase client library.

More generally, when you are debugging a program that uses multiple threads it's possible to create a situation in which a deadlock will occur. Whenever the next or step commands are issued, gdb lets only the thread being debugged execute. All other threads are suspended until the command is completed. Therefore, if you attempt to step over a line of code which tries to communicate with another thread, the program will deadlock.

To deal with problems like this, a "run-all-threads" option has been added to gdb. This option controls whether all of the threads should execute while single-stepping. The default value for this option is "off". In order to prevent a deadlock like that described above, issue the following command in gdb:

set run-all-threads on

We recommend that you use this option only if you're experiencing a deadlock. Allowing other threads to execute while stepping through code can produce confusing results if, for example, the other threads are changing the values of global data.

 

Dynamic Link-Editor Support

gdb has been known to hang or crash if you run a program that uses a dynamic shared library (such as a framework or bundle), then recompile the dynamic shared library, and run the program again. If this happens, you should quit gdb and start a new debugging session every time you rebuild the library. You can use the .gdbinit file to help re-establish things such as breakpoints that you need in your debugging session.

 

Interrupting with Control-C During Dynamic Symbol Loading

Immediately after you start your program running under gdb, the program will start to load dynamic shared libraries, and gdb will begin reading symbols from these libraries. If you attempt to interrupt gdb by typing Control-C during this process, the debugger will be left in a confused internal state from which the only known recovery is to quit the debugger and start over.

 

Setting BOOL Values in Code Without Debugging Symbols or using NSDebug.h

When gdb debugs code without debugging symbols, it assumes variables are of size sizeof(int). Setting or displaying a BOOL (or any non-int) value will usually lead to incorrect results. In particular, setting a BOOL value will cause the next three bytes of memory to be overwritten. For example, if you have four BOOL values declared, setting the first one will cause the next three to acquire unexpected values. Of course, if you have only one BOOL variable and you set it, whatever is next to it in memory is likely to get trashed. This problem does not occur in code containing debugging symbols as gdb knows exactly how big the variable in question is.

This problem prevents setting the global debugging variables declared in Foundation for debugging Objective-C programs; see:
/Library/Frameworks/Foundation.Framework/Headers/NSDebug.h
The workaround for this problem is to set the debugging variables via the command-line or via the environment.

 

Automatic Breakpoint in start()

Due to the way that gdb interacts with the dynamic link editor at startup, there is always a breakpoint inserted at start()+24. It is there to avoid a particularly nasty race condition that prevents gdb from talking to the dynamic link editor properly. After gdb stops at this breakpoint, you must continue the target.

 

Debugging Child Processes

It has been observed that gdb sometimes gets confused when its target process creates a child process and that child process crashes. gdb incorrectly reports that parent process has crashed.

 

Stack Backtrace is Only Three Frames Deep

The Objective-C runtime system catches when messages are sent to some freed Objective-C objects; when this happens, a message like this appears in your console:

objc: FREED(id): message XXX sent to freed object=0x13d938

The runtime system calls abort(). In this case however, gdb is unable to print the backtrace beyond the third stack frame. Thus it is not possible to determine the backtrace which resulted in sending the message to a freed object. The workaround is to set a breakpoint at _freedHandler, which is a function in the Objective-C runtime. This breakpoint is hit just before the call to abort() and gdb can provide a valid backtrace.

 

Known Problems for gdb-4.17


 

Notes Specific to jdb

New Features

The jdb command-line debugger from JavaSoft is included in the Developer Release 2 of both Rhapsody and Yellow Box for Windows. You can find the documentation for jdb Rhapsody at:

http://java.sun.com/products/jdk/1.1/docs/tooldocs/solaris/jdb.html

and for Windows at:

http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/jdb.html

 

Known Problems

jdb Does not Work With "Pure Yellow Box Java"

Yellow Box Java applications, that is, those that subclass from NSPureApplication and are started with the java command, do not work with jdb. For example, this command fails:

jdb com.apple.yellow.application.NSPureApplication -YBJavaApplicationPath /<wherever>/TextEdit.app"

 

 

Notes Specific to Project Builder Debugging

Project Builder provides integrated, visual debugging of programs through the Launcher panel (). This panel can be used to run or debug executables built by your project.

 

New Features

The following new features have been added to Project Builder for debugging since the Developer Release.

 

Known Problems

These new bugs have appeared since the Developer Release.

No Java Debugger on Windows

The integrated Java debugger for use with Project Builder is not yet available on Windows. Check the Apple Developer World Web site for the latest status (http://devworld.apple.com/rhapsody/)

 

No mixed stack backtrace

The stack back trace from the Java debugger includes only Java frames. Calls to native methods are not shown.

 

Only Debug Yellow Box Java Applications

There is no debugging support for Java applets or 100% Pure Java applications.

 

Setting Breakpoints Before Running

You cannot set breakpoints in Java code before the debugger is running. As the Java VM starts up, there is a race condition between the starting of the debugger and the starting of the application. Therefore, some of your code will execute before the debugger becomes active and you are not able to set a breakpoint in this code.

Reference 

2224584

Problem

No -g passed to javac when making target "debug".

Description

To get fully local symbols in .class files, the .java files in your project have to be compiled with the -g option. Unfortunately, due to a bug in the pb_makefiles, this is not done.

Workaround

In the Project Builder Build Panel, click the build options button(). Set the Arguments field to "OTHER_JAVAC_FLAGS=-g". This will pass the -g flag to javac. If you build the project from the command line, you can use "make OTHER_JAVAC_FLAGS=-g". Be sure to clean (click ) the project and then rebuild (click ) to ensure that every Java file is compiled with this flag.


 

Java Debugger Command Reference

Overview

This file summarizes the commands for the Java debugger, which is available through Project Builder. The complete set of commands is given below. Any unique command prefix is recognized (e.g. "du" for "dump"). If a prefix is not unique, the debugger will tell you. Several commands have short aliases (for example, "si" for "stepi" and "bt" for "backtrace"). The case of a command does not matter (for instance, "Break" = "break" = "BrEaK"). The case of arguments may matter (for example, class and file names must match case: "Exception" is not the same as "exception").

JavaBug>> mumble
 ERROR: No command prefix matches "mumble"
b <fileName>:<lineNum> | <class>:<method> -- set a breakpoint
backtrace -- backtrace: show stack info
break <fileName>:<lineNum> | <class>:<method> -- set a breakpoint
bt -- backtrace: show stack info
catch className -- catch exceptions for exception class className
clear Num -- clear (delete) breakpoint number Num
continue -- continue execution from a breakpoint
dir [path] -- get or set dir(ectory) search path
disable Num -- disable breakpoint number Num
down [Num] -- set default frame down Num|1 frames
drop className -- drop (stop catching) exceptions for class className
dump object -- print object's struct(ure)
enable Num -- enable breakpoint number Num
finish -- step Out (finish executing current stack frame)
frame [Num] -- show stack frame info for stack[Num] or current frame
getprop name -- get system property
group [groupName] -- if groupName then set curent thread group,
else show information for thread groups and their threads
list -- list source lines around current frame (if available)
next -- step Over<p* object -- print object's struct(ure)
po object -- invoke object's toString() method
print object -- invoke object's toString() method
resume -- resume all threads
si -- execute a single bytecode instruction (step into)
step -- step Into
stepi -- execute a single bytecode instruction (step into)
suspend -- suspend all threads
thread threadNum -- set current thread to threadNum
up [Num] -- set default frame up Num|1 frames
 

 

Thread Commands

In the Java debugger, there is a current thread group and a current thread. When an exception occurs, the current thread is reset. The current thread group is always the thread group containing the current thread.

Group [groupName]   This command lists thread groups and threads. If a groupName is given, the current thread group is set to that name. To avoid confusion ,thread groups are referred to by name, while threads within a group are referred to by number.

Thread threadNum  This command sets the thread within the current thread group. To find out the current group and thread, type group.

 

Examples:

JavaBug>> group

Group: system 1 Finalizer thread cond. waiting 2 JavaBug cond. waiting 3 Debugger agent running 4 Breakpoint handler cond. waiting 5 Step handler cond. waiting 6 Agent input cond. waiting 7 main suspended< Group: main 1 main suspended  CURRENT GROUP is "system" CURRENT THREAD within the group is "main"  JavaBug>> thread 6  Current thread now Agent input, state=cond. waiting  

Backtrace   This command displays the contents of the current thread's Java stack. (Currently, only Java stack frames are printed. No "native" (non-Java) frames appear). An alias for backtrace is bt.

JavaBug>> bt
 [0] java.io.PipedInputStream.read (PipedInputStream:201) pc = 80
[1] java.io.PipedInputStream.read (PipedInputStream:242) pc = 43
[2] java.io.BufferedInputStream.fill (BufferedInputStream:135) pc = 164
[3] java.io.BufferedInputStream.read (BufferedInputStream:162) pc = 12
[4] java.io.FilterInputStream.read (FilterInputStream:81) pc = 4
[5] sun.tools.debug.AgentIn.run (AgentIn:46) pc = 20
[6] java.lang.Thread.run (Thread:474) pc = 11
 

Stack inspection commands (frame, up, down, print, dump) require that the thread being inspected is suspended. Threads are suspended by hitting a breakpoint, or by the suspend command.

 

Frame [frameNum]  This command displays the arguments and local variables for the current frame or the frame number frameNum . Frame numbers are absolute and are the numbers displayed in the backtrace. Note that Java code must have been compiled with javac's -g flag or local and argument information is not available to the debugger. The frame command resets the current frame.

JavaBug>> backtrace
 [0] com.apple.alpha.core.MutableDictionary.<init> (MutableDictionary:213) pc = 0
[1] Document.setRichText (Document:534) pc = 10<[2] Document.toggleRich (Document:596) pc = 69
 JavaBug>> frame 1
 [1] setRichText(flag=true)
<local> view = <NSTextView: 0x194b8c0>Frame = {{0.00, 0.00}, {490.00, 420.00}}, Bounds = {{0.00, 0.00}, {490.00, 420.00}}
Horizontally resizable: NO, Vertically resizable: YES
MinSize = {490.00, 420.00}, MaxSize = {340282346638528859811704183484516925440.00, 340282346638528859811704183484516925440.00}
 

Up [numFrames]   This command resets the current frame up (toward older frames => higher frame numbers) relative to the current frame. If numFrames is not given, 1 is used.

 

Down [numFrames]  This command resets the current frame down (toward newer frames => lower frame numbers) relative to the current frame. If numFrames is not given, 1 is used.

 

Print object This command prints the object object by calling its toString() method. An alias for print is po (for Print Object).

JavaBug>> po view
 view = <NSTextView: 0x194b8c0>Frame = {{0.00, 0.00}, {490.00, 420.00}}, Bounds = {{0.00, 0.00}, {490.00, 420.00}}
Horizontally resizable: NO, Vertically resizable: YES
MinSize = {490.00, 420.00}, MaxSize = {340282346638528859811704183484516925440.00, 340282346638528859811704183484516925440.00}
 

Dump object  This command prints the object object structurally. An alias for dump is p* (from gdb usage for Print *=reference).

JavaBug>> p* view
view = (com.apple.alpha.app.TextView)0x3bc0c0 {
private int instance = 26523840
}
 JavaBug>> p* 0x3bc0c0
 0x3bc0c0 = (com.apple.alpha.app.TextView)0x3bc0c0 {
private int instance = 26523840
}
 

(In the above case, the object is obviously a native object with a peer class.)

 

List  This command displays source text for the current frame--when it can find it. (Note the dir command, below).

JavaBug>> break Document:setRichText
 Set breakpoint 2000 in method: setRichText at line 533 in file "Document.java"
 JavaBug>> cont
 JavaBug>> // breakpoint hit because of user action
Broken at 533 in "Document.java"
 JavaBug>> list
 File: "Document.java"
529 return layoutManager().hyphenationFactor();
530 }
531
532 public void setRichText(boolean flag) {
533 => TextView view = firstTextView();
534 MutableDictionary textAttributes = new MutableDictionary(2);
535
536 isRichText = flag;
537
 

 

Control Functions

Suspend  This command suspends all Java threads (which are not involved in debugging).

Resume  This command resumes all Java threads (which are not involved in debugging).

Break [fileName:lineNumber]  This command sets a breakpoint in file fileName at line lineNumber . An alias for break is b. With no arguments, it prints the current breakpoints.

Break [ClassName:methodName]  This command sets a breakpoint at the start of method methodName in class ClassName . An alias for break is b. With no arguments, it prints the current breakpoints.

JavaBug>> break Document:setRichText
 Set breakpoint 2000 in method: setRichText at line 533 in file "Document.java"
 JavaBug>> break
 break <fileName>:<lineNum> | <class>:<method> -- set a breakpoint
2000 Document.java:533
 JavaBug>> disable 2000
 JavaBug>> break
break <fileName>:<lineNum> | <class>:<method> -- set a breakpoint
 2000 Document.java:533 [disabled]
 

Clear [breakNum]  This command clears (forgets) the breakpoint numbered breakNum . With no argument, it prints the current breakpoints.

Disable [breakNum]  This command disables, but does not clear, the breakpoint numbered breakNum .

Enable [breakNum]  This command (re)enables the breakpoint numbered breakNum .

Continue  When a thread is broken, this command continues (resumes) execution of that thread.

Step  This command steps forward a line of code. If the code is a call, it steps into the call. If the call is to "native" (non-java) code, it steps over the code (acts like next ). If the step returns to native code, it acts like continue .

Setpi  This command steps forward by a single bytecode instruction. It otherwise acts like step . (Currently, there is no command to display the bytecodes. Use "javap -c classFile " to see the bytecodes).

Next  This command steps forward a line of code. If the code is a call, it steps over the call. If the step returns to native code, it acts like continue .

Finish  This command steps to the end of the code in the current stack frame. (also know as "step out").

Catch ExceptionClass  This command causes exceptions for class ExceptionClass and all its subclasses to act like a breakpoint. (At this time one cannot step through exception code one can only inspect the stack and continue ).

Drop ExceptionClass  This command is the inverse of catch. The system will no longer break when an exception of class ExceptionClass is thrown.

 

Convience Functions

Dir [newClassPath]  This command prints or sets the CLASSPATH used to search for debug and source information (e.g. for the list and frame commands).

GetProp [propName]  This command prints the value for the specified property or all properties of the Java VM. JVM properties cannot be changed.

JavaBug>> getprop user.home
 /Local/Users/kend
 JavaBug>> getprop
 Property Names:
user.language = "en"
java.home = "/Library/Frameworks/JavaVM.framework/Home"
awt.toolkit = "com.apple.rhapsody.awt.RToolkit"
file.encoding.pkg = "sun.io"
java.version = "internal_build:kend:03/05/98-09:08"
file.separator = "/"
line.separator = "
 file.encoding = "MacRoman"
java.compiler = "jitc_ppc"
java.protocol.handler.pkgs = "com.apple.net.protocol"
java.vendor = "Apple Computer, Inc."
user.timezone = "PST"
user.name = "kend"
os.arch = "ppc"
os.name = "Rhapsody"
java.vendor.url = "http://www.apple.com/"
user.dir = "/Local/Users/kend/Projects/TextEdit"
java.class.path = "/Local/Users/kend/Projects/TextEdit/TextEdit.app/Resources/Java/.:.:/Local/Users/kend/jdk20build/build/classes:/System/Library/Java:/Library/Frameworks/JavaVM.framework/Classes/classes.jar:/Library/Frameworks/JavaVM.framework/Classes/awt.jar"
java.class.version = "45.3"
os.version = "Premier Release"
path.separator = ":"
user.home = "/Local/Users/kend"